import time
import json
from pathlib import Path
import ctypes
import platform
import threading
import os
import tkinter as tk
from tkinter import ttk
import mss
import mss.tools
from cnocr import CnOcr
from datetime import datetime
import argparse
import sys

# 根据操作系统选择合适的库加载方式
if platform.system() == 'Windows':
    import ctypes.wintypes

    user32 = ctypes.WinDLL('user32', use_last_error=True)
    gdi32 = ctypes.WinDLL('gdi32', use_last_error=True)
    imm32 = ctypes.WinDLL('imm32', use_last_error=True)
else:
    # Linux系统不支持Windows API，提供空实现
    class MockWinDLL:
        def __getattr__(self, name):
            def mock_func(*args, **kwargs):
                print(f"Mock {name} called")
                return 0

            return mock_func


    user32 = MockWinDLL()
    gdi32 = MockWinDLL()
    imm32 = MockWinDLL()


    # 定义必要的常量
    class wintypes:
        HWND = ctypes.c_void_p
        HDC = ctypes.c_void_p
        DWORD = ctypes.c_uint32
        COLORREF = ctypes.c_uint32
        SIZE = ctypes.c_int * 2
        POINT = ctypes.c_int * 2
        LPARAM = ctypes.c_long
        WPARAM = ctypes.c_ulonglong


    ctypes.wintypes = wintypes

# 定义常量
HWND_DESKTOP = 0
SRCCOPY = 0x00CC0020
TRANSPARENT = 0x0001  # 透明背景模式
OPAQUE = 0x0002  # 不透明背景模式
RGB_RED = 0x000000FF  # 红色(0x00BBGGRR格式)
RGB_YELLOW = 0x0000FFFF  # 黄色
RGB_GREEN = 0x0000FF00  # 绿色
RGB_BLUE = 0x00FF0000  # 蓝色

# 键盘相关常量
# 字母键
VK_A = 0x41  # A键
VK_B = 0x42  # B键
VK_C = 0x43  # C键
VK_D = 0x44  # D键
VK_E = 0x45  # E键
VK_F = 0x46  # F键
VK_G = 0x47  # G键
VK_H = 0x48  # H键
VK_I = 0x49  # I键
VK_J = 0x4A  # J键
VK_K = 0x4B  # K键
VK_L = 0x4C  # L键
VK_M = 0x4D  # M键
VK_N = 0x4E  # N键
VK_O = 0x4F  # O键
VK_P = 0x50  # P键
VK_Q = 0x51  # Q键
VK_R = 0x52  # R键
VK_S = 0x53  # S键
VK_T = 0x54  # T键
VK_U = 0x55  # U键
VK_V = 0x56  # V键
VK_W = 0x57  # W键
VK_X = 0x58  # X键
VK_Y = 0x59  # Y键
VK_Z = 0x5A  # Z键

# 数字键
VK_0 = 0x30  # 0键
VK_1 = 0x31  # 1键
VK_2 = 0x32  # 2键
VK_3 = 0x33  # 3键
VK_4 = 0x34  # 4键
VK_5 = 0x35  # 5键
VK_6 = 0x36  # 6键
VK_7 = 0x37  # 7键
VK_8 = 0x38  # 8键
VK_9 = 0x39  # 9键

# 功能键
VK_F1 = 0x70  # F1键
VK_F2 = 0x71  # F2键
VK_F3 = 0x72  # F3键
VK_F4 = 0x73  # F4键
VK_F5 = 0x74  # F5键
VK_F6 = 0x75  # F6键
VK_F7 = 0x76  # F7键
VK_F8 = 0x77  # F8键
VK_F9 = 0x78  # F9键
VK_F10 = 0x79  # F10键
VK_F11 = 0x7A  # F11键
VK_F12 = 0x7B  # F12键

# 控制键
VK_CONTROL = 0x11  # Ctrl键
VK_SHIFT = 0x10  # Shift键
VK_ALT = 0x12  # Alt键
VK_CAPITAL = 0x14  # Caps Lock键
VK_ESCAPE = 0x1B  # Esc键
VK_SPACE = 0x20  # 空格键
VK_TAB = 0x09  # Tab键
VK_BACK = 0x08  # Backspace键
VK_RETURN = 0x0D  # Enter键
VK_DELETE = 0x2E  # Delete键

# 方向键
VK_UP = 0x26  # 上箭头键
VK_DOWN = 0x28  # 下箭头键
VK_LEFT = 0x25  # 左箭头键
VK_RIGHT = 0x27  # 右箭头键

# 导航键
VK_HOME = 0x24  # Home键
VK_END = 0x23  # End键
VK_PRIOR = 0x21  # Page Up键
VK_NEXT = 0x22  # Page Down键
VK_INSERT = 0x2D  # Insert键

# 其他键
VK_LWIN = 0x5B  # 左Windows键
VK_RWIN = 0x5C  # 右Windows键
VK_APPS = 0x5D  # 应用程序键
VK_SLEEP = 0x5F  # Sleep键

# 数字小键盘键
VK_NUMPAD0 = 0x60  # 小键盘0
VK_NUMPAD1 = 0x61  # 小键盘1
VK_NUMPAD2 = 0x62  # 小键盘2
VK_NUMPAD3 = 0x63  # 小键盘3
VK_NUMPAD4 = 0x64  # 小键盘4
VK_NUMPAD5 = 0x65  # 小键盘5
VK_NUMPAD6 = 0x66  # 小键盘6
VK_NUMPAD7 = 0x67  # 小键盘7
VK_NUMPAD8 = 0x68  # 小键盘8
VK_NUMPAD9 = 0x69  # 小键盘9
VK_MULTIPLY = 0x6A  # 小键盘*
VK_ADD = 0x6B  # 小键盘+
VK_SEPARATOR = 0x6C  # 小键盘,
VK_SUBTRACT = 0x6D  # 小键盘-
VK_DECIMAL = 0x6E  # 小键盘.
VK_DIVIDE = 0x6F  # 小键盘/

# 键盘事件标志
KEYEVENTF_EXTENDEDKEY = 0x0001
KEYEVENTF_KEYUP = 0x0002

# 鼠标事件常量
MOUSEEVENTF_RIGHTDOWN = 0x0008  # 鼠标右键按下
MOUSEEVENTF_RIGHTUP = 0x0010  # 鼠标右键释放

# 输入法相关常量
KLF_ACTIVATE = 0x00000001
KLF_SUBSTITUTE_OK = 0x00000002
ENGLISH_LAYOUT_ID = "00000409"  # 英文(美国)键盘布局ID

# 函数原型原型定义
user32.GetDC.argtypes = [ctypes.wintypes.HWND]
user32.GetDC.restype = ctypes.wintypes.HDC

user32.ReleaseDC.argtypes = [ctypes.wintypes.HWND, ctypes.wintypes.HDC]
user32.ReleaseDC.restype = ctypes.c_int

user32.GetSystemMetrics.argtypes = [ctypes.c_int]
user32.GetSystemMetrics.restype = ctypes.c_int

user32.UpdateWindow.argtypes = [ctypes.wintypes.HWND]
user32.UpdateWindow.restype = ctypes.c_bool

user32.GetKeyState.argtypes = [ctypes.c_int]
user32.GetKeyState.restype = ctypes.wintypes.SHORT

user32.keybd_event.argtypes = [ctypes.c_byte, ctypes.c_byte, ctypes.c_ulong, ctypes.c_ulong]
user32.keybd_event.restype = None

user32.mouse_event.argtypes = [ctypes.c_ulong, ctypes.c_long, ctypes.c_long, ctypes.c_long, ctypes.c_ulong]
user32.mouse_event.restype = None

user32.LoadKeyboardLayoutW.argtypes = [ctypes.c_wchar_p, ctypes.c_uint]
user32.LoadKeyboardLayoutW.restype = ctypes.wintypes.HKL

user32.ActivateKeyboardLayout.argtypes = [ctypes.wintypes.HKL, ctypes.c_uint]
user32.ActivateKeyboardLayout.restype = ctypes.wintypes.HKL

user32.GetForegroundWindow.argtypes = []
user32.GetForegroundWindow.restype = ctypes.wintypes.HWND

user32.GetWindowThreadProcessId.argtypes = [ctypes.wintypes.HWND, ctypes.POINTER(ctypes.wintypes.DWORD)]
user32.GetWindowThreadProcessId.restype = ctypes.wintypes.DWORD

imm32.ImmGetContext.argtypes = [ctypes.wintypes.HWND]
imm32.ImmGetContext.restype = ctypes.c_void_p

imm32.ImmSetConversionStatus.argtypes = [ctypes.c_void_p, ctypes.wintypes.DWORD, ctypes.wintypes.DWORD]
imm32.ImmSetConversionStatus.restype = ctypes.c_bool

imm32.ImmReleaseContext.argtypes = [ctypes.wintypes.HWND, ctypes.c_void_p]
imm32.ImmReleaseContext.restype = ctypes.c_bool

gdi32.CreateCompatibleDC.argtypes = [ctypes.wintypes.HDC]
gdi32.CreateCompatibleDC.restype = ctypes.wintypes.HDC

gdi32.CreateCompatibleBitmap.argtypes = [ctypes.wintypes.HDC, ctypes.c_int, ctypes.c_int]
gdi32.CreateCompatibleBitmap.restype = ctypes.wintypes.HBITMAP

gdi32.SelectObject.argtypes = [ctypes.wintypes.HDC, ctypes.wintypes.HGDIOBJ]
gdi32.SelectObject.restype = ctypes.wintypes.HGDIOBJ

gdi32.DeleteObject.argtypes = [ctypes.wintypes.HGDIOBJ]
gdi32.DeleteObject.restype = ctypes.c_bool

gdi32.DeleteDC.argtypes = [ctypes.wintypes.HDC]
gdi32.DeleteDC.restype = ctypes.c_bool

gdi32.BitBlt.argtypes = [ctypes.wintypes.HDC, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int,
                         ctypes.wintypes.HDC, ctypes.c_int, ctypes.c_int, ctypes.c_uint]
gdi32.BitBlt.restype = ctypes.c_bool

gdi32.CreateFontW.argtypes = [ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int,
                              ctypes.c_uint, ctypes.c_uint, ctypes.c_uint, ctypes.c_uint, ctypes.c_uint,
                              ctypes.c_uint, ctypes.c_uint, ctypes.c_uint, ctypes.c_wchar_p]
gdi32.CreateFontW.restype = ctypes.wintypes.HFONT

gdi32.TextOutW.argtypes = [ctypes.wintypes.HDC, ctypes.c_int, ctypes.c_int, ctypes.c_wchar_p, ctypes.c_int]
gdi32.TextOutW.restype = ctypes.c_bool

gdi32.SetTextColor.argtypes = [ctypes.wintypes.HDC, ctypes.wintypes.COLORREF]
gdi32.SetTextColor.restype = ctypes.wintypes.COLORREF

gdi32.SetBkMode.argtypes = [ctypes.wintypes.HDC, ctypes.c_int]
gdi32.SetBkMode.restype = ctypes.c_int

gdi32.GetTextExtentPoint32W.argtypes = [ctypes.wintypes.HDC, ctypes.c_wchar_p, ctypes.c_int,
                                        ctypes.POINTER(ctypes.wintypes.SIZE)]
gdi32.GetTextExtentPoint32W.restype = ctypes.c_bool

# 全局变量 - 当前选中的种族
current_race = "人族"
race_lock = threading.Lock()

# 全局变量 - 计时开始时间
timer_start_time = None
timer_lock = threading.Lock()

# 全局变量 - 计时是否正在运行
timing_running = False
timing_lock = threading.Lock()


def switch_to_english_input():
    """切换到英文输入法"""
    try:
        # 方法1：使用LoadKeyboardboardLayout和ActivateKeyboardLayout切换键盘布局
        print("正在正在切换到英文输入法...")

        # 加载英文键盘布局
        hkl = user32.LoadKeyboardLayoutW(ENGLISH_LAYOUT_ID, KLF_ACTIVATE | KLF_SUBSTITUTE_OK)
        if not hkl:
            raise ctypes.WinError(ctypes.get_last_error())

        # 激活英文键盘布局
        result = user32.ActivateKeyboardLayout(hkl, KLF_ACTIVATE)
        if not result:
            raise ctypes.WinError(ctypes.get_last_error())

        # 方法2：额外确保当前窗口的输入法也切换到英文
        hwnd = user32.GetForegroundWindow()
        if hwnd:
            # 获取当前窗口的线程ID
            thread_id = user32.GetWindowThreadProcessId(hwnd, None)

            # 获取输入法上下文
            ime_context = imm32.ImmGetContext(hwnd)
            if ime_context:
                # 设置输入法为英文模式
                imm32.ImmSetConversionStatus(ime_context, 0, 0)
                imm32.ImmReleaseContext(hwnd, ime_context)

        print("已成功切换到英文输入法")
        return True


    except Exception as e:
        print(f"切换输入法失败: {str(e)}")
        # 如果方法1失败，尝试方法3：模拟按下Alt+Shift切换
        try:
            print("尝试使用Alt+Shift快捷键切换输入法...")
            user32.keybd_event(VK_ALT, 0, 0, 0)
            user32.keybd_event(VK_SHIFT, 0, 0, 0)
            time.sleep(0.1)
            user32.keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0)
            user32.keybd_event(VK_ALT, 0, KEYEVENTF_KEYUP, 0)
            print("已发送Alt+Shift快捷键")
            return True
        except Exception as e2:
            print(f"快捷键切换也失败: {str(e2)}")
            return False


def load_time_texts(json_path="time_texts.json"):
    """读取JSON配置文件"""
    if not Path(json_path).exists():
        default_data = {
            "0分:10秒": "别发呆",
            "0分:30秒": "下2矿",
            "1分:00秒": "下3矿",
            "1分:30秒": "起飞"
        }
        with open(json_path, "w", encoding="utf-8") as f:
            json.dump(default_data, f, ensure_ascii=False, indent=2)
        return default_data

    with open(json_path, "r", encoding="utf-8") as f:
        return json.load(f)


def get_current_race():
    """获取当前选中的种族"""
    global current_race
    with race_lock:
        return current_race


def set_current_race(race):
    """设置当前选中的种族"""
    global current_race
    with race_lock:
        current_race = race


def get_race_config(race_name, config_type=None):
    """获取指定种族的配置"""
    config = load_keyboard_config()
    race_section = config.get("种族", {}).get(race_name, {})

    if config_type:
        return race_section.get(config_type, {})
    return race_section


def load_keyboard_config(json_path="keyboard_config.json"):
    """读取键盘配置JSON文件"""
    if not Path(json_path).exists():
        default_data = {
            "global_shortcuts": {
                "start_timing": {
                    "keys": ["ctrl", "f10"],
                    "description": "启动计时和中文提示"
                },
                "exit_program": {
                    "keys": ["ctrl", "shift", "f10"],
                    "description": "退出整个程序"
                }
            },
            "种族": {
                "人族": {
                    "start_auto_key": {
                        "keys": ["ctrl", "f11"],
                        "description": "启动自动按键序列",
                        "auto_key_sequence": {
                            "duration_minutes": 1,
                            "duration_interval_seconds": 3,
                            "actions": [
                                {
                                    "key": "5",
                                    "times": 2,
                                    "interval": 10,
                                    "after_interval": 30
                                },
                                {
                                    "key": "s",
                                    "times": 3,
                                    "interval": 10
                                }
                            ]
                        }
                    },
                    "stop_auto_key": {
                        "keys": ["ctrl", "shift", "f11"],
                        "description": "停止自动按键序列"
                    },
                    "keyboard_shortcuts": [
                        {
                            "trigger_key": "q",
                            "actions": [
                                {"key": "9", "times": 3, "interval": 1000, "after_interval": 10000},
                                {"key": "n", "times": 2, "interval": 1000}
                            ]
                        },
                        {
                            "trigger_key": "w",
                            "actions": [
                                {"key": "0", "times": 1, "interval": 1000}
                            ]
                        }
                    ],
                    "mouse_shortcuts": [
                        {
                            "trigger_event": "left_click",
                            "actions": [
                                {"key": "f5", "times": 1, "interval": 100}
                            ]
                        },
                        {
                            "trigger_event": "right_click",
                            "actions": [
                                {"key": "esc", "times": 1, "interval": 100}
                            ]
                        },
                        {
                            "trigger_event": "wheel_up",
                            "actions": [
                                {"key": "up", "times": 3, "interval": 100}
                            ]
                        },
                        {
                            "trigger_event": "wheel_down",
                            "actions": [
                                {"key": "down", "times": 3, "interval": 100}
                            ]
                        }
                    ]
                },
                "神族": {
                    "start_auto_key": {
                        "keys": ["ctrl", "f11"],
                        "description": "启动自动按键序列",
                        "auto_key_sequence": {
                            "duration_minutes": 1,
                            "duration_interval_seconds": 3,
                            "actions": [
                                {
                                    "key": "6",
                                    "times": 2,
                                    "interval": 10,
                                    "after_interval": 30
                                },
                                {
                                    "key": "d",
                                    "times": 3,
                                    "interval": 10
                                }
                            ]
                        }
                    },
                    "stop_auto_key": {
                        "keys": ["ctrl", "shift", "f11"],
                        "description": "停止神族自动按键序列"
                    },
                    "keyboard_shortcuts": [
                        {
                            "trigger_key": "q",
                            "actions": [
                                {"key": "8", "times": 25, "interval": 10, "after_interval": 10},
                                {"key": "right_click", "times": 1, "interval": 10}
                            ]
                        },
                        {
                            "trigger_key": "w",
                            "actions": [
                                {"key": "1", "times": 15, "interval": 10, "after_interval": 10},
                                {"key": "m", "times": 6, "interval": 10}
                            ]
                        }
                    ],
                    "mouse_shortcuts": [
                        {
                            "trigger_event": "right_click",
                            "actions": [
                                {"key": "space", "times": 1, "interval": 100}
                            ]
                        }
                    ]
                },
                "虫族": {
                    "start_auto_key": {
                        "keys": ["ctrl", "f11"],
                        "description": "启动自动按键序列",
                        "auto_key_sequence": {
                            "duration_minutes": 1,
                            "duration_interval_seconds": 3,
                            "actions": [
                                {
                                    "key": "7",
                                    "times": 2,
                                    "interval": 10,
                                    "after_interval": 30
                                },
                                {
                                    "key": "a",
                                    "times": 3,
                                    "interval": 10
                                }
                            ]
                        }
                    },
                    "stop_auto_key": {
                        "keys": ["ctrl", "shift", "f11"],
                        "description": "停止虫族自动按键序列"
                    },
                    "keyboard_shortcuts": [
                        {
                            "trigger_key": "q",
                            "actions": [
                                {"key": "7", "times": 35, "interval": 10, "after_interval": 10},
                                {"key": "right_click", "times": 1, "interval": 10}
                            ]
                        },
                        {
                            "trigger_key": "w",
                            "actions": [
                                {"key": "2", "times": 25, "interval": 10, "after_interval": 10},
                                {"key": "b", "times": 10, "interval": 10}
                            ]
                        }
                    ],
                    "mouse_shortcuts": [
                        {
                            "trigger_event": "right_click",
                            "actions": [
                                {"key": "tab", "times": 1, "interval": 100}
                            ]
                        }
                    ]
                }
            }
        }
        with open(json_path, "w", encoding="utf-8") as f:
            json.dump(default_data, f, ensure_ascii=False, indent=2)
        return default_data

    with open(json_path, "r", encoding="utf-8") as f:
        config = json.load(f)

        # 确保配置文件结构正确
        if "global_shortcuts" not in config:
            config["global_shortcuts"] = {
                "start_timing": {
                    "keys": ["ctrl", "f10"],
                    "description": "启动计时和中文提示"
                },
                "exit_program": {
                    "keys": ["ctrl", "shift", "f10"],
                    "description": "退出整个程序"
                }
            }

        if "种族" not in config:
            config["种族"] = {}

        # 确保三个种族都存在
        if "人族" not in config["种族"]:
            config["种族"]["人族"] = {
                "start_auto_key": {
                    "keys": ["ctrl", "f11"],
                    "description": "启动自动按键序列",
                    "auto_key_sequence": {
                        "duration_minutes": 1,
                        "duration_interval_seconds": 3,
                        "actions": [
                            {
                                "key": "5",
                                "times": 2,
                                "interval": 10,
                                "after_interval": 30
                            },
                            {
                                "key": "s",
                                "times": 3,
                                "interval": 10
                            }
                        ]
                    }
                },
                "stop_auto_key": {
                    "keys": ["ctrl", "shift", "f11"],
                    "description": "停止自动按键序列"
                },
                "keyboard_shortcuts": [],
                "mouse_shortcuts": []
            }

        if "神族" not in config["种族"]:
            config["种族"]["神族"] = {
                "start_auto_key": {
                    "keys": ["ctrl", "f11"],
                    "description": "启动自动按键序列",
                    "auto_key_sequence": {
                        "duration_minutes": 1,
                        "duration_interval_seconds": 3,
                        "actions": [
                            {
                                "key": "6",
                                "times": 2,
                                "interval": 10,
                                "after_interval": 30
                            },
                            {
                                "key": "d",
                                "times": 3,
                                "interval": 10
                            }
                        ]
                    }
                },
                "stop_auto_key": {
                    "keys": ["ctrl", "shift", "f11"],
                    "description": "停止神族自动按键序列"
                },
                "keyboard_shortcuts": [],
                "mouse_shortcuts": []
            }

        if "虫族" not in config["种族"]:
            config["种族"]["虫族"] = {
                "start_auto_key": {
                    "keys": ["ctrl", "f11"],
                    "description": "启动自动按键序列",
                    "auto_key_sequence": {
                        "duration_minutes": 1,
                        "duration_interval_seconds": 3,
                        "actions": [
                            {
                                "key": "7",
                                "times": 2,
                                "interval": 10,
                                "after_interval": 30
                            },
                            {
                                "key": "a",
                                "times": 3,
                                "interval": 10
                            }
                        ]
                    }
                },
                "stop_auto_key": {
                    "keys": ["ctrl", "shift", "f11"],
                    "description": "停止虫族自动按键序列"
                },
                "keyboard_shortcuts": [],
                "mouse_shortcuts": []
            }

        return config


def get_available_races():
    """获取可用的种族列表"""
    config = load_keyboard_config()
    return list(config.get("种族", {}).keys())


def create_gui():
    """创建Tkinter GUI界面"""
    # 创建主窗口
    root = tk.Tk()
    root.title("星际争霸争霸辅助工具")
    root.geometry("350x150")
    root.resizable(False, False)

    # 设置窗口透明度（30%）
    root.attributes("-alpha", 0.3)

    # 设置窗口置顶
    root.attributes("-topmost", True)

    # 设置窗口背景色
    root.configure(bg="#2c2c2c")

    # 创建Notebook控件（Tab页）
    notebook = ttk.Notebook(root)
    notebook.pack(fill='both', expand=True, padx=5, pady=5)

    # 创建第一个个Tab页（主控制页）
    tab1 = ttk.Frame(notebook)
    notebook.add(tab1, text='主控制')

    # 创建个Tab页（预留页）
    tab2 = ttk.Frame(notebook)
    notebook.add(tab2, text='高级设置')

    # 在个Tab页添加提示文本
    tab2_label = tk.Label(tab2, text='此功能正在开发中...', bg="#2c2c2c", fg="white", font=("微软雅黑", 12))
    tab2_label.pack(pady=30)

    # 将窗口移动到屏幕右上角
    root.update_idletasks()
    width = root.winfo_width()
    height = root.winfo_height()
    x = root.winfo_screenwidth() - width - 80
    y = 200
    root.geometry('{}x{}+{}+{}'.format(width, height, x, y))

    # 创建框架来容纳控件，使用grid布局
    control_frame = tk.Frame(tab1, bg="#2c2c2c")
    control_frame.pack(pady=5, padx=5, fill='both', expand=True)

    # 创建Start按钮
    def start_timing():
        """开始计时并在桌面显示文字"""
        global timing_running

        # 检查是否已有计时在运行
        with timing_lock:
            if timing_running:
                # 在桌面显示提示
                draw_animated_text("已有自动桌面提示在运行", size=60, x=400, y=350, color=RGB_YELLOW, sleepseconds=1)
                print("\n已有自动桌面提示在运行")
                return

            # 设置计时状态为运行中
            timing_running = True

        print("\n点击Start按钮，开始计时...")

        # 在桌面画出"逻辑开始"中文字
        draw_animated_text("逻辑开始", size=80, x=500, y=300, color=RGB_GREEN, sleepseconds=0.5)

        # 设置计时开始时间
        global timer_start_time
        with timer_lock:
            timer_start_time = int(time.time())

        # 启动计时线程
        timer_thread = threading.Thread(target=show_classification_text)
        timer_thread.daemon = True
        timer_thread.start()

    start_button = tk.Button(control_frame, text="启动中文提示", command=start_timing, bg="#4CAF50", fg="white",
                             font=("微软雅黑", 10))
    start_button.grid(row=0, column=0, pady=(5, 5), padx=(5, 5), sticky='ew')

    # 创建已过期时间标签（使用富文本）
    passed_time_label = tk.Text(control_frame, height=1, width=25, bg="#2c2c2c", fg="white", font=("微软雅黑", 10),
                                relief="flat")
    passed_time_label.grid(row=0, column=1, pady=(5, 5), padx=(5, 5), sticky='ew')
    passed_time_label.insert("1.0", "计时: ", "small")
    passed_time_label.insert("end", "0分0秒", "large_red")
    passed_time_label.config(state="disabled")

    # 配置文本标签样式
    passed_time_label.tag_configure("small", font=("微软雅黑", 10))
    passed_time_label.tag_configure("large_red", font=("微软雅黑", 14, "bold"), foreground="red")

    # 创建种族选择标签
    race_label = tk.Label(control_frame, text="选择种族:", bg="#2c2c2c", fg="white", font=("微软雅黑", 10))
    race_label.grid(row=1, column=0, pady=(5, 5), padx=(5, 5), sticky='w')

    # 获取可用种族列表
    races = get_available_races()
    if not races:
        races = ["人族", "神族", "虫族"]

    # 创建种族选择下拉框
    race_var = tk.StringVar(root)
    race_var.set(get_current_race())  # 设置当前选中的种族

    def on_race_change(*args):
        """种族选择变化时的回调函数"""
        selected_race = race_var.get()
        current_race = get_current_race()
        if selected_race != current_race:
            set_current_race(selected_race)
            draw_animated_text(f"已切换到{selected_race}", size=80, x=500, y=500, color=RGB_GREEN, sleepseconds=0.5)
            print(f"\n已切换到{selected_race}配置")

    race_combobox = ttk.Combobox(control_frame, textvariable=race_var, values=races, state="readonly",
                                 font=("微软雅黑", 10))
    race_combobox.grid(row=1, column=1, pady=(5, 5), padx=(5, 5), sticky='ew')
    race_combobox.bind("<<ComboboxSelected>>", on_race_change)

    # 创建状态标签
    status_label = tk.Label(control_frame, text="当前种族: 人族", bg="#2c2c2c", fg="white", font=("微软雅黑", 10))
    status_label.grid(row=2, column=0, columnspan=2, pady=(5, 5), padx=(5, 5), sticky='ew')

    # 设置列权重，使控件能够适应窗口大小
    control_frame.columnconfigure(0, weight=1)
    control_frame.columnconfigure(1, weight=1)

    # 更新状态标签和下拉框的函数
    def update_gui():
        """更新状态标签和下拉框"""
        current_race = get_current_race()
        auto_key_status = "运行中" if auto_key_running else "已停止"

        # 获取计时状态
        with timing_lock:
            timing_status = "运行中" if timing_running else "已停止"

        # 计算计时时间
        with timer_lock:
            if timer_start_time:
                elapsed = int(time.time()) - timer_start_time
                minutes = elapsed // 60
                seconds = elapsed % 60
                timer_text = f"{minutes}分{seconds}秒"
            else:
                timer_text = "0分0秒"

        # 更新时间标签，使时间部分显示为红色
        status_label.config(text=f"当前种族: {current_race}")

        # 更新富文本标签
        passed_time_label.config(state="normal")
        passed_time_label.delete("1.0", "end")

        # 插入不同颜色和大小的文本
        passed_time_label.insert("1.0", "已过去时间: ", "small")
        passed_time_label.insert("end", timer_text, "large_red")
        passed_time_label.insert("end", f" ({timing_status})", "small")

        # 配置文本标签样式
        passed_time_label.tag_configure("small", font=("微软雅黑", 10))
        passed_time_label.tag_configure("large_red", font=("微软雅黑", 15, "bold"), foreground="red")

        passed_time_label.config(state="disabled")

        # 更新下拉框选择
        if race_var.get() != current_race:
            race_var.set(current_race)

        # 检查是否需要重新设置标签样式
        if passed_time_label['font'] != ("微软雅黑", 12, "bold"):
            passed_time_label.config(font=("微软雅黑", 12, "bold"))

        root.after(100, update_gui)

    # 启动GUI更新
    update_gui()

    # 窗口关闭事件处理
    def on_close():
        """关闭窗口时终止所有线程"""
        global auto_key_running, timing_running
        auto_key_running = False
        with timing_lock:
            timing_running = False
        print("程序已退出")
        os._exit(0)

    root.protocol("WM_DELETE_WINDOW", on_close)

    # 运行主循环
    root.mainloop()


def switch_race(direction):
    """切换种族配置"""
    races = get_available_races()
    if not races:
        print("没有可用的种族配置")
        return

    current = get_current_race()
    current_index = races.index(current) if current in races else 0

    if direction == "next":
        new_index = (current_index + 1) % len(races)
    elif direction == "prev":
        new_index = (current_index - 1) % len(races)
    else:
        return

    new_race = races[new_index]
    set_current_race(new_race)

    # 在桌面显示种族切换提示
    draw_animated_text(f"已切换到{new_race}", size=80, x=500, y=500, color=RGB_GREEN, sleepseconds=0.5)
    print(f"\n已切换到{new_race}配置")

    return new_race


def draw_transparent_text(text, size=100, x=100, y=100, color=RGB_RED, font_name="SimHei"):
    """在内存DC中使用透明背景绘制文字并显示到桌面"""
    try:
        # 获取桌面设备上下文
        hdc_screen = user32.GetDC(HWND_DESKTOP)
        if not hdc_screen:
            raise ctypes.WinError(ctypes.get_last_error())

        # 创建内存设备上下文(内存DC)
        hdc_mem = gdi32.CreateCompatibleDC(hdc_screen)
        if not hdc_mem:
            raise ctypes.WinError(ctypes.get_last_error())

        # 创建字体
        hfont = gdi32.CreateFontW(
            size, 0, 0, 0, 400,  # 高度、宽度、角度、方向、粗细
            0, 0, 0, 1, 4,  # 斜体、下划线、删除线、字符集、输出精度
            0, 0, 0, font_name  # 剪辑精度、质量、间距、字体
        )
        if not hfont:
            raise ctypes.WinError(ctypes.get_last_error())

        try:
            # 选入字体
            hfont_old = gdi32.SelectObject(hdc_mem, hfont)
            if not hfont_old:
                raise ctypes.WinError(ctypes.get_last_error())

            # 获取文本尺寸
            text_size = ctypes.wintypes.SIZE()
            if not gdi32.GetTextExtentPoint32W(hdc_mem, text, len(text), ctypes.byref(text_size)):
                raise ctypes.WinError(ctypes.get_last_error())

            # 创建兼容位图
            w, h = text_size.cx + 20, text_size.cy + 20  # 增加一些边距
            hbm_mem = gdi32.CreateCompatibleBitmap(hdc_screen, w, h)
            if not hbm_mem:
                raise ctypes.WinError(ctypes.get_last_error())

            # 将位图选入内存DC
            hbm_old = gdi32.SelectObject(hdc_mem, hbm_mem)
            if not hbm_old:
                raise ctypes.WinError(ctypes.get_last_error())

            try:
                # 关键步骤：将内存DC中的文字背景设置为透明
                prev_mode = gdi32.SetBkMode(hdc_mem, TRANSPARENT)
                if prev_mode == 0:
                    raise ctypes.WinError(ctypes.get_last_error())

                # 设置文字颜色
                gdi32.SetTextColor(hdc_mem, color)

                # 在内存DC上绘制文字（背景已设置为透明）
                if not gdi32.TextOutW(hdc_mem, 10, 10, text, len(text)):
                    raise ctypes.WinError(ctypes.get_last_error())

                # 将内存DC内容复制到屏幕
                if not gdi32.BitBlt(hdc_screen, x, y, w, h, hdc_mem, 0, 0, SRCCOPY):
                    raise ctypes.WinError(ctypes.get_last_error())

                print(f"已绘制透明背景的文字: {text}")
                return (x, y, w, h)  # 返回绘制区域的坐标和尺寸


            finally:
                # 恢复原背景模式
                gdi32.SetBkMode(hdc_mem, prev_mode)
                # 清理资源
                gdi32.SelectObject(hdc_mem, hbm_old)
                gdi32.DeleteObject(hbm_mem)


        finally:
            # 恢复原字体
            gdi32.SelectObject(hdc_mem, hfont_old)
            gdi32.DeleteObject(hfont)

        # 释放桌面DC
        user32.ReleaseDC(HWND_DESKTOP, hdc_screen)


    except Exception as e:
        print(f"绘制错误: {str(e)}")
    return None


def clear_desktop_area(x, y, w, h):
    """清除桌面上指定区域的内容"""
    try:
        # 获取桌面设备上下文
        hdc_screen = user32.GetDC(HWND_DESKTOP)
        if not hdc_screen:
            raise ctypes.WinError(ctypes.get_last_error())

        # 创建内存设备上下文
        hdc_mem = gdi32.CreateCompatibleDC(hdc_screen)
        if not hdc_mem:
            raise ctypes.WinError(ctypes.get_last_error())

        # 创建兼容位图
        hbm_mem = gdi32.CreateCompatibleBitmap(hdc_screen, w, h)
        if not hbm_mem:
            raise ctypes.WinError(ctypes.get_last_error())

        # 将位图选入内存DC
        hbm_old = gdi32.SelectObject(hdc_mem, hbm_mem)
        if not hbm_old:
            raise ctypes.WinError(ctypes.get_last_error())

        try:
            # 将桌面背景复制到内存DC
            if not gdi32.BitBlt(hdc_mem, 0, 0, w, h, hdc_screen, x, y, SRCCOPY):
                raise ctypes.WinError(ctypes.get_last_error())

            # 延迟一下再清除
            time.sleep(3)

            # 将原始背景复制回桌面，清除文字
            if not gdi32.BitBlt(hdc_screen, x, y, w, h, hdc_mem, 0, 0, SRCCOPY):
                raise ctypes.WinError(ctypes.get_last_error())

            print(f"已清除区域: x={x}, y={y}, w={w}, h={h}")


        finally:
            # 清理资源
            gdi32.SelectObject(hdc_mem, hbm_old)
            gdi32.DeleteObject(hbm_mem)
            gdi32.DeleteDC(hdc_mem)

        # 释放桌面DC
        user32.ReleaseDC(HWND_DESKTOP, hdc_screen)


    except Exception as e:
        print(f"清除错误: {str(e)}")


def draw_animated_text(text, size=100, x=100, y=100, color=RGB_RED, font_name="SimHei", sleepseconds=0.5):
    """绘制带有淡入淡出动画的文字"""
    try:
        # 获取桌面设备上下文
        hdc_screen = user32.GetDC(HWND_DESKTOP)
        if not hdc_screen:
            raise ctypes.WinError(ctypes.get_last_error())

        # 创建内存设备上下文
        hdc_mem = gdi32.CreateCompatibleDC(hdc_screen)
        if not hdc_mem:
            raise ctypes.WinError(ctypes.get_last_error())

        # 创建字体
        hfont = gdi32.CreateFontW(
            size, 0, 0, 0, 400,  # 高度、宽度、角度、方向、粗细
            0, 0, 0, 1, 4,  # 斜体、下划线、删除线、字符集、输出精度
            0, 0, 0, font_name  # 剪辑精度、质量、间距、字体
        )
        if not hfont:
            raise ctypes.WinError(ctypes.get_last_error())

        try:
            # 选入字体
            hfont_old = gdi32.SelectObject(hdc_mem, hfont)
            if not hfont_old:
                raise ctypes.WinError(ctypes.get_last_error())

            # 获取文本尺寸
            text_size = ctypes.wintypes.SIZE()
            if not gdi32.GetTextExtentPoint32W(hdc_mem, text, len(text), ctypes.byref(text_size)):
                raise ctypes.WinError(ctypes.get_last_error())

            # 创建兼容位图
            w, h = text_size.cx + 20, text_size.cy + 20  # 增加一些边距
            hbm_mem = gdi32.CreateCompatibleBitmap(hdc_screen, w, h)
            if not hbm_mem:
                raise ctypes.WinError(ctypes.get_last_error())

            # 将位图选入内存DC
            hbm_old = gdi32.SelectObject(hdc_mem, hbm_mem)
            if not hbm_old:
                raise ctypes.WinError(ctypes.get_last_error())

            try:
                # 保存原始背景
                hdc_bg = gdi32.CreateCompatibleDC(hdc_screen)
                hbm_bg = gdi32.CreateCompatibleBitmap(hdc_screen, w, h)
                gdi32.SelectObject(hdc_bg, hbm_bg)
                gdi32.BitBlt(hdc_bg, 0, 0, w, h, hdc_screen, x, y, SRCCOPY)

                # 设置透明背景
                prev_mode = gdi32.SetBkMode(hdc_mem, TRANSPARENT)
                gdi32.SetTextColor(hdc_mem, color)

                # 淡入效果
                for alpha in range(0, 256, 10):
                    # 清除内存DC
                    gdi32.BitBlt(hdc_mem, 0, 0, w, h, hdc_bg, 0, 0, SRCCOPY)

                    # 绘制文字
                    gdi32.TextOutW(hdc_mem, 10, 10, text, len(text))

                    # 复制到屏幕
                    gdi32.BitBlt(hdc_screen, x, y, w, h, hdc_mem, 0, 0, SRCCOPY)

                    # 同样可以节约一点时间
                    # time.sleep(0.02)

                # 保持显示3秒
                time.sleep(sleepseconds)

                # 淡出效果
                for alpha in range(255, -1, -10):
                    # 清除内存DC
                    gdi32.BitBlt(hdc_mem, 0, 0, w, h, hdc_bg, 0, 0, SRCCOPY)

                    # 绘制文字
                    gdi32.TextOutW(hdc_mem, 10, 10, text, len(text))

                    # 复制到屏幕
                    gdi32.BitBlt(hdc_screen, x, y, w, h, hdc_mem, 0, 0, SRCCOPY)

                    time.sleep(0.02)

                # 恢复原始背景
                gdi32.BitBlt(hdc_screen, x, y, w, h, hdc_bg, 0, 0, SRCCOPY)

                print(f"已绘制动画文字: {text}")


            finally:
                # 恢复原背景模式
                gdi32.SetBkMode(hdc_mem, prev_mode)
                # 清理资源
                gdi32.SelectObject(hdc_mem, hbm_old)
                gdi32.DeleteObject(hbm_mem)
                gdi32.DeleteDC(hdc_bg)
                gdi32.DeleteObject(hbm_bg)


        finally:
            # 恢复原字体
            gdi32.SelectObject(hdc_mem, hfont_old)
            gdi32.DeleteObject(hfont)

        # 释放桌面DC
        user32.ReleaseDC(HWND_DESKTOP, hdc_screen)


    except Exception as e:
        print(f"动画绘制错误: {str(e)}")


def show_classification_text():
    """主函数：监控时间并在桌面上显示相应文本"""
    # 加载时间-文本配置并转换为秒数
    time_texts = load_time_texts()
    timed_events = {}
    for time_str, text in time_texts.items():
        try:
            minutes, seconds = time_str.split("分:")
            seconds = seconds.replace("秒", "").strip()
            total_seconds = int(minutes) * 60 + int(seconds)
            timed_events[total_seconds] = text
        except Exception as e:
            print(f"JSON格式错误，跳过无效条目 {time_str}：{e}")

    # 获取屏幕尺寸
    screen_width = user32.GetSystemMetrics(0)  # SM_CXSCREEN
    screen_height = user32.GetSystemMetrics(1)  # SM_CYSCREEN
    print(f"屏幕尺寸: {screen_width}x{screen_height}")

    start_time = int(time.time())
    displayed_events = set()
    event_positions = []  # 存储已显示事件的位置和尺寸

    # 颜色列表，循环使用
    colors = [RGB_RED, RGB_YELLOW, RGB_GREEN, RGB_BLUE]
    color_index = 0

    print("计时已开始...")
    print(f"设置的时间点: {timed_events}")

    try:
        while True:
            elapsed = int(time.time()) - start_time

            # 显示经过的时间
            minutes = elapsed // 60
            seconds = elapsed % 60
            print(f"\r已过去: {minutes}分{seconds}秒", end="", flush=True)

            # 检查是否需要显示新事件
            if elapsed in timed_events and elapsed not in displayed_events:
                text = timed_events[elapsed]
                color = colors[color_index % len(colors)]
                color_index += 1

                # 计算显示位置（在屏幕上部分布）
                event_count = len(event_positions)
                x = 900
                y = 200 + event_count * 120  # 每个事件间隔120像素

                # 确保不超出屏幕高度
                if y + 100 > screen_height:
                    y = screen_height - 150

                print(f"\n时间点 {minutes}分{seconds}秒: {text}")

                # 绘制带有动画效果的文字
                draw_animated_text(text, size=80, x=x, y=y, color=color, sleepseconds=2)

                displayed_events.add(elapsed)

            time.sleep(0.1)


    except KeyboardInterrupt:
        print("\n程序正在退出...")

        # 清理所有显示的文字
        for pos in event_positions:
            if pos:
                clear_desktop_area(*pos)

        print("程序已退出")
    finally:
        # 重置计时状态
        global timing_running
        with timing_lock:
            timing_running = False


def is_key_pressed(key_code):
    """检查指定键是否被按下"""
    return (user32.GetKeyState(key_code) & 0x8000) != 0


def check_key_combination(keys):
    """检查指定的组合键是否被按下"""
    if not keys:
        return False

    # 键名到虚拟键码的映射
    key_map = {
        'ctrl': VK_CONTROL,
        'shift': VK_SHIFT,
        'alt': VK_ALT,
        'f1': VK_F1,
        'f2': VK_F2,
        'f3': VK_F3,
        'f4': VK_F4,
        'f5': VK_F5,
        'f6': VK_F6,
        'f7': VK_F7,
        'f8': VK_F8,
        'f9': VK_F9,
        'f10': VK_F10,
        'f11': VK_F11,
        'f12': VK_F12,
        'esc': VK_ESCAPE,
        'enter': VK_RETURN,
        'space': VK_SPACE,
        'tab': VK_TAB,
        'backspace': VK_BACK,
        'delete': VK_DELETE,
        'home': VK_HOME,
        'end': VK_END,
        'pageup': VK_PRIOR,
        'pagedown': VK_NEXT,
        'up': VK_UP,
        'down': VK_DOWN,
        'left': VK_LEFT,
        'right': VK_RIGHT
    }

    # 转换键名到虚拟键码
    key_codes = []
    for key in keys:
        key = key.lower()
        if key in key_map:
            key_codes.append(key_map[key])
        elif len(key) == 1 and key.isalpha():
            # 字母键
            key_codes.append(ord(key.upper()))
        else:
            print(f"不支持的键: {key}")
            return False

    # 检查所有键是否都被按下
    for code in key_codes:
        if not is_key_pressed(code):
            return False

    return True


# 全局变量，用于控制auto_key_sequence线程
auto_key_thread = None
auto_key_running = False


def keyboard_listener():
    """键盘监听线程函数 - 监听全局快捷键"""
    # 加载键盘配置
    input_config = load_keyboard_config()
    global_shortcuts = input_config.get('global_shortcuts', {})

    start_keys = global_shortcuts.get('start_timing', {}).get('keys', ['ctrl', 'f10'])
    exit_keys = global_shortcuts.get('exit_program', {}).get('keys', ['ctrl', 'shift', 'f10'])

    print("键盘监听已启动，等待以下快捷键:")
    print(f"  启动计时: {'+'.join(start_keys)}")
    print(f"  退出程序: {'+'.join(exit_keys)}")
    print(f"  切换种族(上): Ctrl+Up")
    print(f"  切换种族(下): Ctrl+Down")

    timer_started = False
    global auto_key_thread, auto_key_running, timer_start_time

    # 种族切换快捷键状态
    prev_race_up_state = False
    prev_race_down_state = False

    while True:
        # 检查启动计时快捷键
        if check_key_combination(start_keys):
            # 检查是否已有计时在运行
            with timing_lock:
                if timing_running:
                    if not timer_started:  # 只显示一次提示
                        # 在桌面显示提示
                        draw_animated_text("已有自动桌面提示在运行", size=60, x=400, y=350, color=RGB_YELLOW,
                                           sleepseconds=1)
                        print("\n已有自动桌面提示在运行")
                    timer_started = True  # 防止重复显示提示
                    time.sleep(0.5)  # 等待按键释放
                    continue

                # 设置计时状态为运行中
                timing_running = True

            print(f"\n检测到 {'+'.join(start_keys)}，开始计时...")

            # 在桌面画出"逻辑开始"中文字
            draw_animated_text("逻辑开始", size=80, x=500, y=300, color=RGB_GREEN, sleepseconds=0.5)

            # 设置计时开始时间
            with timer_lock:
                timer_start_time = int(time.time())

            # 启动计时线程
            timer_thread = threading.Thread(target=show_classification_text)
            timer_thread.daemon = True
            timer_thread.start()

            timer_started = True
            # 等待按键释放
            time.sleep(0.5)

        # 检查种族切换快捷键 - Ctrl+Up
        current_race_up_state = is_key_pressed(VK_CONTROL) and is_key_pressed(VK_UP)
        if current_race_up_state and not prev_race_up_state:
            print("\n检测到 Ctrl+Up，切换到上一个种族...")
            switch_race("prev")
            # 等待按键释放
            time.sleep(0.5)
        prev_race_up_state = current_race_up_state

        # 检查种族切换快捷键 - Ctrl+Down
        current_race_down_state = is_key_pressed(VK_CONTROL) and is_key_pressed(VK_DOWN)
        if current_race_down_state and not prev_race_down_state:
            print("\n检测到 Ctrl+Down，切换到下一个种族...")
            switch_race("next")
            # 等待按键释放
            time.sleep(0.5)
        prev_race_down_state = current_race_down_state

        # 获取当前种族的配置
        current_race_name = get_current_race()
        start_auto_key_config = get_race_config(current_race_name, "start_auto_key")
        stop_auto_key_config = get_race_config(current_race_name, "stop_auto_key")

        start_auto_key_keys = start_auto_key_config.get('keys', ['ctrl', 'f11'])
        stop_auto_key_keys = stop_auto_key_config.get('keys', ['ctrl', 'shift', 'f11'])

        # 检查启动自动按键快捷键
        if not auto_key_running and check_key_combination(start_auto_key_keys):
            print(f"\n检测到 {'+'.join(start_auto_key_keys)}，启动自动按键序列...")

            # 在桌面画出"自动按键开始"中文字
            draw_animated_text("自动按键开始", size=80, x=500, y=400, color=RGB_BLUE, sleepseconds=0.5)

            # 获取自动按键配置
            auto_key_config = start_auto_key_config.get('auto_key_sequence')
            if auto_key_config and isinstance(auto_key_config, dict):
                duration_minutes = auto_key_config.get('duration_minutes', 5)
                actions = auto_key_config.get('actions', [])
                duration_interval_seconds = auto_key_config.get('duration_interval_seconds', 10)

                if actions and isinstance(actions, list):
                    print(f"启动自动按键线程，持续 {duration_minutes} 分钟")
                    auto_key_running = True
                    auto_key_thread = threading.Thread(
                        target=auto_key_press_sequence,
                        args=(actions, duration_minutes, duration_interval_seconds)
                    )
                    auto_key_thread.daemon = True
                    auto_key_thread.start()

            # 等待按键释放
            time.sleep(0.5)

        # 检查停止自动按键快捷键
        if auto_key_running and check_key_combination(stop_auto_key_keys):
            print(f"\n检测到 {'+'.join(stop_auto_key_keys)}，停止自动按键序列...")

            # 在桌面画出"自动按键停止"中文字
            draw_animated_text("自动按键停止", size=80, x=500, y=400, color=RGB_RED, sleepseconds=0.5)

            # 设置标志位停止线程
            auto_key_running = False

            # 等待按键释放
            time.sleep(0.5)

        # 检查退出程序快捷键
        if check_key_combination(exit_keys):
            print(f"\n检测到 {'+'.join(exit_keys)}，退出程序...")
            # 设置标志位停止所有线程
            auto_key_running = False
            # 退出程序
            os.system('taskkill /f /im %s' % 'python.exe')

        time.sleep(0.1)


def get_virtual_key_code(key_char):
    """将字符或键名转换为虚拟键码"""
    key_map = {
        # 数字键
        '0': 0x30, '1': 0x31, '2': 0x32, '3': 0x33, '4': 0x34,
        '5': 0x35, '6': 0x36, '7': 0x37, '8': 0x38, '9': 0x39,

        # 字母键
        'a': 0x41, 'b': 0x42, 'c': 0x43, 'd': 0x44, 'e': 0x45,
        'f': 0x46, 'g': 0x47, 'h': 0x48, 'i': 0x49, 'j': 0x4A,
        'k': 0x4B, 'l': 0x4C, 'm': 0x4D, 'n': 0x4E, 'o': 0x4F,
        'p': 0x50, 'q': 0x51, 'r': 0x52, 's': 0x53, 't': 0x54,
        'u': 0x55, 'v': 0x56, 'w': 0x57, 'x': 0x58, 'y': 0x59, 'z': 0x5A,

        # 功能键
        'f1': 0x70, 'f2': 0x71, 'f3': 0x72, 'f4': 0x73, 'f5': 0x74,
        'f6': 0x75, 'f7': 0x76, 'f8': 0x77, 'f9': 0x78, 'f10': 0x79,
        'f11': 0x7A, 'f12': 0x7B,

        # 控制键
        'escape': 0x1B, 'esc': 0x1B, 'space': 0x20, 'tab': 0x09,
        'backspace': 0x08, 'enter': 0x0D, 'return': 0x0D, 'delete': 0x2E,

        # 方向键
        'up': 0x26, 'down': 0x28, 'left': 0x25, 'right': 0x27,

        # 导航键
        'home': 0x24, 'end': 0x23, 'pageup': 0x21, 'pgup': 0x21,
        'pagedown': 0x22, 'pgdn': 0x22, 'insert': 0x2D, 'ins': 0x2D,

        # 数字小键盘键
        'numpad0': 0x60, 'numpad1': 0x61, 'numpad2': 0x62, 'numpad3': 0x63,
        'numpad4': 0x64, 'numpad5': 0x65, 'numpad6': 0x66, 'numpad7': 0x67,
        'numpad8': 0x68, 'numpad9': 0x69, 'multiply': 0x6A, 'add': 0x6B,
        'subtract': 0x6D, 'decimal': 0x6E, 'divide': 0x6F
    }
    return key_map.get(key_char.lower(), 0)


def simulate_key_press(key_code):
    """模拟按下并释放一个键"""
    # 按下键
    user32.keybd_event(key_code, 0, 0, 0)
    time.sleep(0.01)  # 短暂延迟
    # 释放键
    user32.keybd_event(key_code, 0, KEYEVENTF_KEYUP, 0)


def simulate_mouse_right_click():
    """模拟鼠标右键点击"""
    # 获取当前鼠标位置
    cursor_pos = ctypes.wintypes.POINT()
    user32.GetCursorPos(ctypes.byref(cursor_pos))

    # 模拟鼠标右键按下
    user32.mouse_event(MOUSEEVENTF_RIGHTDOWN, cursor_pos.x, cursor_pos.y, 0, 0)
    time.sleep(0.01)  # 短暂延迟
    # 模拟鼠标右键释放
    user32.mouse_event(MOUSEEVENTF_RIGHTUP, cursor_pos.x, cursor_pos.y, 0, 0)


def simulate_key_sequence(actions):
    """根据配置模拟一系列键位动作"""
    print(f"开始执行键位序列: {actions}")

    for action in actions:
        key = action.get('key', '')
        times = int(action.get('times', 1))
        interval = int(action.get('interval', 1000))
        after_interval = int(action.get('after_interval', 0))

        # 检查是否是鼠标右键点击
        if key.lower() == 'right_click':
            print(f"执行动作: 鼠标右键点击, 次数:{times}, 间隔:{interval}ms")

            # 执行指定次数的鼠标右键点击
            for i in range(times):
                simulate_mouse_right_click()
                if i < times - 1:  # 最后一次不等待
                    time.sleep(interval / 1000)
        else:
            key_code = get_virtual_key_code(key)
            if key_code == 0:
                print(f"不支持的键: {key}")
                continue

            print(f"执行动作: 键'{key}'({hex(key_code)}), 次数:{times}, 间隔:{interval}ms")

            # 执行指定次数的按键
            for i in range(times):
                simulate_key_press(key_code)
                if i < times - 1:  # 最后一次不等待
                    time.sleep(interval / 1000)

        # 执行完当前动作后的等待时间
        if after_interval > 0:
            print(f"动作后等待 {after_interval}ms")
            time.sleep(after_interval / 1000)

    print("键位序列执行完成")


def auto_key_press_sequence(actions, duration_minutes, duration_interval_seconds):
    # duration_interval_seconds: 在整个时间段内，需要间隔停止的秒数
    """自动按键序列 - 在指定分钟内循环执行按键动作"""
    print(f"自动按键序列开始，持续 {duration_minutes} 分钟")

    end_time = time.time() + duration_minutes * 60
    sequence_index = 0
    global auto_key_running

    while time.time() < end_time and auto_key_running:
        # 循环执行动作序列
        current_action = actions[sequence_index % len(actions)]

        key = current_action.get('key', '')
        times = int(current_action.get('times', 1))
        interval = int(current_action.get('interval', 1000))
        after_interval = int(current_action.get('after_interval', 0))

        print(f"自动执行: {current_action}")

        # 执行当前动作
        if key.lower() == 'right_click':
            for i in range(times):
                if not auto_key_running:  # 检查是否需要停止
                    break
                simulate_mouse_right_click()
                if i < times - 1:
                    time.sleep(interval / 1000)
        else:
            key_code = get_virtual_key_code(key)
            if key_code != 0:
                for i in range(times):
                    if not auto_key_running:  # 检查是否需要停止
                        break
                    simulate_key_press(key_code)
                    if i < times - 1:
                        time.sleep(interval / 1000)

        # 如果配置了after_interval，那么就需要等待，如果没有配置，那么就不需要等待
        if after_interval > 0:
            time.sleep(after_interval / 1000)

        # 切换到下一个动作
        sequence_index += 1

        # 已经完成一轮了所有按键了，那么就需要进行时间上的一轮等待，下轮才可以完整的按完一轮按键
        if sequence_index >= len(actions):
            # 动作后等待，以保证时间之间的间隔
            if duration_interval_seconds > 0:
                time.sleep(duration_interval_seconds)

                # 保证下轮循环，是重新开始的
                sequence_index = 0

        # 检查是否超时或需要停止
        if time.time() >= end_time or not auto_key_running:
            break

    print(f"自动按键序列结束，已持续 {duration_minutes} 分钟")
    auto_key_running = False  # 重置运行状态


def input_event_listener():
    """输入事件监听线程 - 监听键盘和鼠标事件并执行对应的键位序列"""

    print("输入事件监听已启动，等待事件触发...")

    # 鼠标状态变量
    mouse_state = {
        'left_button': False,
        'right_button': False,
        'wheel_delta': 0
    }

    # 键盘状态变量 - 用于边缘检测
    keyboard_state = {}

    # 鼠标钩子相关变量
    WH_MOUSE_LL = 14
    WM_LBUTTONDOWN = 0x0201
    WM_LBUTTONUP = 0x0202
    WM_RBUTTONDOWN = 0x0204
    WM_RBUTTONUP = 0x0205
    WM_MOUSEWHEEL = 0x020A

    # 定义MOUSEHOOKSTRUCT结构
    class MOUSEHOOKSTRUCT(ctypes.Structure):
        _fields_ = [
            ("pt", ctypes.wintypes.POINT),
            ("hwnd", ctypes.wintypes.HWND),
            ("wHitTestCode", ctypes.c_uint),
            ("dwExtraInfo", ctypes.wintypes.LPARAM)
        ]

    # 定义MSLLHOOKSTRUCT结构（用于低级鼠标钩子）
    class MSLLHOOKSTRUCT(ctypes.Structure):
        _fields_ = [
            ("pt", ctypes.wintypes.POINT),
            ("mouseData", ctypes.c_uint),
            ("flags", ctypes.c_uint),
            ("time", ctypes.c_uint),
            ("dwExtraInfo", ctypes.wintypes.LPARAM)
        ]

    # 鼠标钩子回调函数
    def mouse_hook_proc(nCode, wParam, lParam):
        if nCode >= 0:
            # 左键按下
            if wParam == WM_LBUTTONDOWN:
                mouse_state['left_button'] = True
            # 左键释放
            elif wParam == WM_LBUTTONUP:
                mouse_state['left_button'] = False
            # 右键按下
            elif wParam == WM_RBUTTONDOWN:
                mouse_state['right_button'] = True
            # 右键释放
            elif wParam == WM_RBUTTONUP:
                mouse_state['right_button'] = False
            # 鼠标滚轮
            elif wParam == WM_MOUSEWHEEL:
                # 解析MSLLHOOKSTRUCT结构
                msll_struct = ctypes.cast(lParam, ctypes.POINTER(MSLLHOOKSTRUCT)).contents
                # 获取滚轮 delta 值，正为向上，负为向下
                wheel_delta = ctypes.c_int16(msll_struct.mouseData >> 16).value
                mouse_state['wheel_delta'] = wheel_delta

        # 调用下一个钩子
        return user32.CallNextHookEx(None, nCode, wParam, lParam)

    # 设置鼠标钩子
    CMPFUNC = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.POINTER(ctypes.c_void_p))
    mouse_hook = CMPFUNC(mouse_hook_proc)
    mouse_hook_handle = user32.SetWindowsHookExW(WH_MOUSE_LL, mouse_hook, None, 0)

    if not mouse_hook_handle:
        print(f"设置鼠标钩子失败: {ctypes.WinError(ctypes.get_last_error())}")
        return

    try:
        while True:
            # 获取当前种族的配置
            current_race_name = get_current_race()
            keyboard_shortcuts = get_race_config(current_race_name, "keyboard_shortcuts")
            mouse_shortcuts = get_race_config(current_race_name, "mouse_shortcuts")

            # 准备键盘快捷键配置
            keyboard_configs = []
            for shortcut in keyboard_shortcuts:
                trigger_key = shortcut.get('trigger_key', '')
                actions = shortcut.get('actions', [])

                if not trigger_key or not isinstance(actions, list):
                    print(f"无效的键盘快捷键配置: {shortcut}")
                    continue

                trigger_key_code = get_virtual_key_code(trigger_key)
                if trigger_key_code == 0:
                    print(f"无效的键盘触发键: {trigger_key}")
                    continue

                keyboard_configs.append({
                    'trigger_type': 'keyboard',
                    'trigger_key': trigger_key,
                    'trigger_key_code': trigger_key_code,
                    'actions': actions,
                    'key_pressed': False  # 用于边缘检测
                })

            # 准备鼠标快捷键配置
            mouse_configs = []
            mouse_trigger_map = {
                'left_click': 'left_click',
                'right_click': 'right_click',
                'wheel_up': 'wheel_up',
                'wheel_down': 'wheel_down'
            }

            for shortcut in mouse_shortcuts:
                trigger_event = shortcut.get('trigger_event', '').lower()
                actions = shortcut.get('actions', [])

                if trigger_event not in mouse_trigger_map or not isinstance(actions, list):
                    print(f"无效的鼠标快捷键配置: {shortcut}")
                    continue

                mouse_configs.append({
                    'trigger_type': 'mouse',
                    'trigger_event': trigger_event,
                    'actions': actions,
                    'event_triggered': False  # 用于边缘检测
                })

            # 检查键盘事件
            for config in keyboard_configs:
                # 检查触发键状态
                current_state = (user32.GetKeyState(config['trigger_key_code']) & 0x8000) != 0

                # 检测按键按下事件（边缘检测）
                if current_state and not config['key_pressed']:
                    config['key_pressed'] = True
                    print(f"\n检测到键盘 '{config['trigger_key']}' 键按下，执行键位序列...")

                    # 启动键位模拟线程
                    key_thread = threading.Thread(target=simulate_key_sequence, args=(config['actions'],))
                    key_thread.daemon = True
                    key_thread.start()

                    # 等待一段时间，防止重复触发。按键一次，仅仅触发一次事件。
                    time.sleep(0.4)


                # 检测按键释放事件
                elif not current_state and config['key_pressed']:
                    config['key_pressed'] = False

            # 检查鼠标事件
            # 左键点击
            if mouse_state['left_button']:
                for config in mouse_configs:
                    if config['trigger_event'] == 'left_click' and not config['event_triggered']:
                        config['event_triggered'] = True
                        print(f"\n检测到鼠标左键点击，执行键位序列...")

                        # 启动键位模拟线程
                        key_thread = threading.Thread(target=simulate_key_sequence, args=(config['actions'],))
                        key_thread.daemon = True
                        key_thread.start()
            else:
                # 重置左键点击状态
                for config in mouse_configs:
                    if config['trigger_event'] == 'left_click':
                        config['event_triggered'] = False

            # 右键点击
            if mouse_state['right_button']:
                for config in mouse_configs:
                    if config['trigger_event'] == 'right_click' and not config['event_triggered']:
                        config['event_triggered'] = True
                        print(f"\n检测到鼠标右键点击，执行键位序列...")

                        # 启动键位模拟线程
                        key_thread = threading.Thread(target=simulate_key_sequence, args=(config['actions'],))
                        key_thread.daemon = True
                        key_thread.start()
            else:
                # 重置右键点击状态
                for config in mouse_configs:
                    if config['trigger_event'] == 'right_click':
                        config['event_triggered'] = False

            # 鼠标滚轮
            if mouse_state['wheel_delta'] != 0:
                if mouse_state['wheel_delta'] > 0:  # 滚轮向上
                    for config in mouse_configs:
                        if config['trigger_event'] == 'wheel_up' and not config['event_triggered']:
                            config['event_triggered'] = True
                            print(f"\n检测到鼠标滚轮向上，执行键位序列...")

                            # 启动键位模拟线程
                            key_thread = threading.Thread(target=simulate_key_sequence, args=(config['actions'],))
                            key_thread.daemon = True
                            key_thread.start()
                else:  # 滚轮向下
                    for config in mouse_configs:
                        if config['trigger_event'] == 'wheel_down' and not config['event_triggered']:
                            config['event_triggered'] = True
                            print(f"\n检测到鼠标滚轮向下，执行键位序列...")

                            # 启动键位模拟线程
                            key_thread = threading.Thread(target=simulate_key_sequence, args=(config['actions'],))
                            key_thread.daemon = True
                            key_thread.start()

                # 重置滚轮状态
                mouse_state['wheel_delta'] = 0
                # 短暂延迟避免重复触发
                time.sleep(1.4)

            # 处理Windows消息
            msg = ctypes.wintypes.MSG()
            user32.PeekMessageW(ctypes.byref(msg), None, 0, 0, 1)

            time.sleep(0.01)


    except KeyboardInterrupt:
        print("\n输入事件监听已停止")


    finally:
        # 移除鼠标钩子
        user32.UnhookWindowsHookEx(mouse_hook_handle)


if __name__ == "__main__":
    try:
        # 仅支持Windows平台
        if platform.system() != 'Windows':
            print("此程序仅支持Windows平台")
            exit(1)

        # 程序启动时自动切换到英文输入法
        switch_to_english_input()

        # 显示当前选中的种族
        print(f"当前选中种族: {current_race}")

        # 启动键盘监听线程（Ctrl+F10开始计时）
        listener_thread = threading.Thread(target=keyboard_listener)
        listener_thread.daemon = True
        listener_thread.start()

        # 启动输入事件监听线程（监听键盘和鼠标事件）
        input_thread = threading.Thread(target=input_event_listener)
        input_thread.daemon = True
        input_thread.start()

        # 启动GUI线程
        gui_thread = threading.Thread(target=create_gui)
        gui_thread.daemon = True
        gui_thread.start()

        # 主线程等待
        while True:
            time.sleep(1)


    except KeyboardInterrupt:
        print("\n程序已退出")
